1 R Session info

print(sessionInfo(), locale = FALSE)
## R version 4.1.2 (2021-11-01)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Pop!_OS 21.10
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.13.so
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] broom_0.7.11    patchwork_1.1.1 forcats_0.5.1   stringr_1.4.0  
##  [5] dplyr_1.0.8     purrr_0.3.4     readr_2.1.1     tidyr_1.2.0    
##  [9] tibble_3.1.6    ggplot2_3.3.5   tidyverse_1.3.1 here_1.0.1     
## 
## loaded via a namespace (and not attached):
##  [1] Rcpp_1.0.8       lubridate_1.8.0  assertthat_0.2.1 rprojroot_2.0.2 
##  [5] digest_0.6.29    utf8_1.2.2       R6_2.5.1         cellranger_1.1.0
##  [9] backports_1.4.1  reprex_2.0.1     evaluate_0.14    httr_1.4.2      
## [13] pillar_1.7.0     rlang_1.0.1      readxl_1.3.1     rstudioapi_0.13 
## [17] jquerylib_0.1.4  rmarkdown_2.11   bit_4.0.4        munsell_0.5.0   
## [21] compiler_4.1.2   modelr_0.1.8     xfun_0.29        pkgconfig_2.0.3 
## [25] htmltools_0.5.2  tidyselect_1.1.1 bookdown_0.24    fansi_1.0.2     
## [29] crayon_1.4.2     tzdb_0.2.0       dbplyr_2.1.1     withr_2.4.3     
## [33] grid_4.1.2       jsonlite_1.7.3   gtable_0.3.0     lifecycle_1.0.1 
## [37] DBI_1.1.2        magrittr_2.0.2   scales_1.1.1     cli_3.1.1       
## [41] stringi_1.7.6    vroom_1.5.7      fs_1.5.2         xml2_1.3.3      
## [45] bslib_0.3.1      ellipsis_0.3.2   generics_0.1.2   vctrs_0.3.8     
## [49] tools_4.1.2      bit64_4.0.5      glue_1.6.1       hms_1.1.1       
## [53] parallel_4.1.2   fastmap_1.1.0    yaml_2.2.2       colorspace_2.0-2
## [57] rvest_1.0.2      knitr_1.37       haven_2.4.3      sass_0.4.0

2 Experimental setup

knitr::include_graphics(here("analysis/supplementary-materials/figures/plate_lid_side.jpg"))
The 24 deepwell plate and the lid with pegs (substrata)

Figure S2.1 The 24 deepwell plate and the lid with pegs (substrata)

knitr::include_graphics(here("analysis/supplementary-materials/figures/plate_lid_on.jpg"))
The 24 deepwell plate with the lid (almost) on.

Figure S2.2 The 24 deepwell plate with the lid (almost) on.

4 Raw data

The raw data can be downloaded from OSF:

Solution counts: https://osf.io/kz3b2/
Sample counts: https://osf.io/kz3b2/

# solution counts
wget https://osf.io/kz3b2/download -O solution_counts.csv

# sample counts
wget https://osf.io/kz3b2/download -O starch_counts.csv

4.1 Metadata for raw data files

Counts represent the absolute number of starches counted on a slide

starch_counts.csv

variable description
sample Sample number.
plate Plate number that the sample came from.
row Which row on the plate the sample came from.
s Small starch count.
m Medium starch count.
l Large starch count.
total Sum of s, m, and l.
treatment Treatment solution to which the samples were exposed.
starch Type of starch that was counted.
weight Weight of the biofilm sample.
vol Total volume of EDTA in which the sample was dissolved.
portion_slide Proportion of the microscope slide that was counted. Total transects on slide divided by counted transects.

solution_counts.csv

variable description
solution Type of starch in solution.
concentration Concentration (%w/v) of starch in solution.
vol_slide Volume of solution added to slide.
vol_total Total volume of solution in aliquot.
portion_slide Proportion of slide that was counted. Total transects on slide divided by counted transects.
slide Slide number.
starch Starch type counted.
s Small starch count.
m Medium starch count.
l Large starch count.
total Sum of s, m, and l.

5 Microscope images

Microscope image of wheat starch from a Potato treatment sample.

Figure S5.1 Microscope image of wheat starch from a Potato treatment sample.

Microscope image of wheat starch from a wheat treatment sample.

Figure S5.2 Microscope image of wheat starch from a wheat treatment sample.

6 Amylase activity

Amylase activity in U/mL enzyme, where U is the amount of enzyme needed to release 1 \(\mu\)mole maltose from starch in six minutes at 36 °C.

Tables containing the amylase activity results for both plates and both photometric readings conducted on each plate. Samples (rows) were analysed in triplicates (columns).

# table of results reported in units amylase per mL enzyme (but let's be honest,
  # ...it doesn't really matter what the unit is. No activity is no activity)
cols <- c("1", "2", "3")  # sample triplicates
rows <- c("S1", "S2", "S3", "B1", "B2", "B3", "B4", "B5", "BT1", "BT2", "BT3")
plt1_ph1_result <- rbind(sal1_ph1, bmm1_ph1)
rownames(plt1_ph1_result) <- rows
plt1_ph2_result <- rbind(sal1_ph2, bmm1_ph2)
rownames(plt1_ph2_result) <- rows
plt2_ph1_result <- rbind(sal2_ph1, bmm2_ph1)
rownames(plt2_ph1_result) <- rows
plt2_ph2_result <- rbind(sal2_ph2, bmm2_ph2)
rownames(plt2_ph2_result) <- rows
Table S6.1 Amylase activity in U/mL for plate 1, photometric read 1.
V1 V2 V3
S1 28.2306584 10.0605214 28.4572187
S2 30.0884529 13.8667346 28.0720662
S3 26.8486405 15.0448483 28.2533144
B1 -0.8602506 -0.7072591 -0.7837549
B2 -0.5670169 -1.0642394 -0.7200084
B3 -0.6180140 -1.2299802 -0.4395239
B4 -0.7965042 -1.2809774 -0.9112478
B5 -0.9877436 -1.0514901 -0.6435126
BT1 -1.4467182 -1.2809774 -1.4212196
BT2 -1.4212196 -0.8857492 -1.4467182
BT3 -1.4849661 -1.2682281 -1.3702225
Table S6.2 Amylase activity in U/mL for plate 1, photometric read 2.
V1 V2 V3
S1 27.9846495 9.9310259 28.0075022
S2 29.8128646 13.8159829 28.1217656
S3 26.7506043 15.0500280 28.3959979
B1 -0.8003496 -0.6852669 -0.7364148
B2 -0.4934625 -1.0305148 -0.6852669
B3 -0.5446104 -1.1967453 -0.4167408
B4 -0.7236278 -1.2478932 -0.8642844
B5 -0.9410061 -1.0305148 -0.6341191
BT1 -1.4013367 -1.2478932 -1.3885497
BT2 -1.3757627 -0.8514974 -1.4013367
BT3 -1.4396975 -1.2351062 -1.3246149
Table S6.3 Amylase activity in U/mL for plate 2, photometric read 1.
V1 V2 V3
S1 28.0673333 10.3602545 26.9474345
S2 30.1803498 13.6354301 27.7503808
S3 26.2501390 15.3892339 27.8560316
B1 -0.7162472 -0.8020671 -0.8020671
B2 -0.5813875 -1.1453464 -0.7652871
B3 -0.5200876 -1.3660261 -0.5446075
B4 -0.8756269 -1.3782860 -0.9859667
B5 -0.7530272 -1.1698664 -0.6794673
BT1 -1.4641059 -1.1943864 -1.3905460
BT2 -1.4641059 -0.8511070 -1.4273259
BT3 -1.5499257 -0.9614468 -1.5131458
Table S6.4 Amylase activity in U/mL for plate 2, photometric read 2.
V1 V2 V3
S1 28.0794000 10.3989036 26.7014237
S2 30.0085669 13.5364497 27.3798120
S3 26.0442349 15.3172192 27.5494091
B1 -0.6620533 -0.7725806 -0.7602997
B2 -0.5515260 -1.1041625 -0.7111765
B3 -0.4778411 -1.3374979 -0.4901219
B4 -0.8462654 -1.3374979 -0.9322311
B5 -0.7234573 -1.1410049 -0.6374916
BT1 -1.4480252 -1.1532857 -1.3620595
BT2 -1.4357443 -0.7971422 -1.3866211
BT3 -1.5094292 -0.9076695 -1.4725868

7 Control samples

raw_counts %>%
  filter(treatment == "control") %>%
  select(!c(vol, portion_slide, s, m, l))

Only the total starch count was considered for control samples, as size was deemed irrelevant.

8 Count corrections

Slide transects were calculated by counting the number of transects on the cover slip under the microscope. This was done by starting in the bottom-left corner, and counting the total number of full fields-of-view across the cover slip to the bottom-right corner. The total number of transects was 29 (verified multiple times).

A 1 mL aliquot of each of the original treatment solutions was taken, from which 10 \(\mu\)L was taken and mounted on a microscope slide and mixed with 10 \(\mu\)L 20% (v/v) glycerol. Solution counts were extrapolated from a slide (10 \(\mu\)L) to the quantity in a 1 ml solution, and then multipled by 16 days to achieve the total number of granules that were exposed to the samples:

\[ \text{corrected count} = \text{raw count} \times \frac{\text{total slides}}{\text{counted slides}} \times 100 \mu L \times 16 \text{ days} \]

Samples were submerged in 50–100 \(\mu\)L EDTA, from which 20 \(\mu\)L was mounted on a microscope slide (\(V_{slide}\)) and counted. Sample counts were extrapolated to the full volume of EDTA (\(V_{sample}\)) in which the sample was submerged (i.e. 50–100 \(\mu\)L).

\[ \text{Corrected count} = \text{raw count} \times (\text{portion of slide})^{-1} \times \frac{V_{sample}}{V_{slide}} \]

9 Some additional plots

Bar plot for the total count of granules exposed to the samples over the duration of the experiment,

sol_long %>%
  filter(size == "total") %>%
  group_by(treatment, starch) %>%
  ggplot(aes(x = treatment, y = count, fill = treatment, col = starch)) +
  geom_col(size = 1.5) +
  theme(panel.background = element_rect(fill = "white"),
        panel.grid = element_line(colour = "grey"),
        panel.grid.major.x = element_blank(),
        axis.title.x = element_blank()) +
  scale_fill_viridis_d() +
  scale_color_viridis_d(begin = 0.5)

and box plot with superimposed points (with added jitter) for the extrapolated mean counts of granules extracted from the samples.

corr_comb %>%
  filter(treatment != "control") %>%
  ggplot(aes(x = treatment, y = total, 
             shape = treatment)) +
    geom_boxplot(aes(fill = treatment), alpha = 0.5) +
    geom_jitter(aes(col = treatment), width = 0.3, size = 2) +
    scale_color_viridis_d() +
    theme(panel.background = element_rect(fill = "white"),
        panel.grid = element_line(colour = "grey"),
        panel.grid.major.x = element_blank(),
        axis.title.x = element_blank()) + # remove y-axis title
    scale_fill_viridis_d()

Extracted-granule counts separated by treatment and size, including error bars:

corr_counts_long %>%
  filter(size != "total",
         treatment != "control") %>%
  group_by(treatment, starch, size) %>%
  summarise(sd = sd(count, na.rm = T),
            count = mean(count, na.rm = T)) %>%
  #mutate(percent = count / sum(count, na.rm = T) * 100) %>% 
  ggplot(aes(x = starch, y = count, fill = size)) +
    geom_col(position = "dodge") +
    geom_errorbar(aes(ymin = count, ymax = count + sd), width = 0.2, position = position_dodge(0.9)) +
    facet_wrap(~ treatment, scales = "free") +
    scale_fill_viridis_d() +
    theme_bw()
## `summarise()` has grouped output by 'treatment', 'starch'. You can override
## using the `.groups` argument.
## Warning: Removed 1 rows containing missing values (geom_col).
l = large, m = medium, s = small.

Figure S9.1 l = large, m = medium, s = small.

Size distribution (in %) within the solutions (top) and samples (bottom):

sol_size_pl <- sol_corr %>%
  group_by(solution, starch) %>%
  summarise(across(c(s, m, l, total), mean, na.rm = T)) %>%
  pivot_longer(cols = c(s,m,l, total), values_to = "count", names_to = "size") %>%
  filter(size != "total") %>%
  group_by(solution, starch) %>%
  mutate(percent = count / sum(count, na.rm = T) * 100) %>% 
  ggplot(aes(x = starch, y = percent, fill = size)) +
    geom_col(position = "dodge") +
    facet_wrap(~ solution, scales = "free_x") +
    scale_fill_viridis_d() +
    theme_bw() +
    labs(x = "")

samp_size_pl <- corr_counts_long %>%
  filter(size != "total",
         treatment != "control") %>%
  group_by(treatment, starch, size) %>%
  summarise(count = mean(count, na.rm = T)) %>%
  mutate(percent = count / sum(count, na.rm = T) * 100) %>% 
  ggplot(aes(x = starch, y = percent, fill = size)) +
    geom_col(position = "dodge") +
    facet_wrap(~ treatment, scales = "free_x") +
    scale_fill_viridis_d() +
    theme_bw()

sol_size_pl / samp_size_pl + plot_layout(guides = "collect")
l = large, m = medium, s = small.

Figure S9.2 l = large, m = medium, s = small.

Separated correlation plots. These are the same plots as in the main paper, just larger.

Scatter plot of sample weight and standardised starch count by z-score for separated treatments.

Figure S9.3 Scatter plot of sample weight and standardised starch count by z-score for separated treatments.

Scatter plot of sample weight in mg and standardised count of starch grains per mg calculus.

Figure S9.4 Scatter plot of sample weight in mg and standardised count of starch grains per mg calculus.

9.1 …and a table

Differences in size ratios (%) of granules between the solutions and the samples. Negative values indicate a loss of granules from solution to sample.

size_diff %>%
  mutate(across(where(is.numeric), signif, 3))